package com.daman

import akka.actor._
import glokka.Registry
import scala.runtime.ScalaRunTime

import xitrum.annotation.WEBSOCKET
import xitrum._



@WEBSOCKET("chat/:id")
class Chat extends WebSocketAction with LookupOrCreateChatRoom{
  def  execute(): Unit = {
    val id = param[String]("id")
    joinChatRoom(id)
  }

  override def onJoinChatRoom(chatRoom: ActorRef): Actor.Receive = {
    case WebSocketText(text) =>
      log.debug("incoming text "+text)
      chatRoom ! ChatRoom.Message(text)
    case ChatRoom.Message(msg) =>
      respondWebSocketJson(Map("hehe"->msg))

    case WebSocketBinary(bytes) =>
      log.info("onBinaryMessage: " + ScalaRunTime.stringOf(bytes))
      respondWebSocketBinary(bytes)

    case WebSocketPing =>
      log.debug("onPing")

    case WebSocketPong =>
      log.debug("onPong")
  }

}

object  ChatRoom{
  case object  Join
  case class Message(msg:String)
  val PROXY_NAME = "chatRoomProxy"
  val registry = Registry.start(Config.actorSystem,PROXY_NAME)
}

class ChatRoom extends  Actor with Log{
  private var subscribers= Seq.empty[ActorRef]
  private var msgs = Seq.empty[String]
  def receive = {
    case ChatRoom.Join =>
      val friend = sender()
      subscribers = subscribers :+ sender()
      log.debug("join chatRoom my is "+friend)
    case m @ChatRoom.Message(msg)=>
      msgs = msgs :+msg
      subscribers.foreach(_ ! m)
    case Terminated(subscriber) =>
       subscribers = subscribers.filterNot(_==subscriber)
      log.debug("left chat room "+subscriber)
  }

}

trait  LookupOrCreateChatRoom extends Log{
  this:Actor =>

  def onJoinChatRoom(chatRoom:ActorRef):Actor.Receive

  def joinChatRoom(id:String) {
    val name = id
    ChatRoom.registry ! Registry.Register(name,Props[ChatRoom])
    log.debug("registry register "+name)
    context.become(waitForRegisterResult())
  }

  private def waitForRegisterResult():Actor.Receive = {
    case msg:Registry.FoundOrCreated =>
      val chatRoom = msg.ref
      log.debug("registry found or created "+chatRoom)
      chatRoom ! ChatRoom.Join
      context.become(onJoinChatRoom(chatRoom))
  }

}

case class OneMessage(from:String,to:String,body:String,time:String)